﻿
using System;
using System.ServiceModel;
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EnterpriseServices.Service
{
    public partial class ValidationManagerRemotingProxy : IDisposable, IValidationManagerRemoting
    {

        /// <summary>
        /// Provides the singleton pattern.
        /// </summary>
        /// <returns></returns>
        public static ValidationManagerRemotingProxy sharedInstance()
        {
            return SHARED_INSTANCE;
        }

        /// <summary>
        /// Initializes this instance.
        /// </summary>
        public void Initialize()
        {
            if( !initialized )
            {
                timeout.AutoReset = true;
                timeout.Elapsed += new System.Timers.ElapsedEventHandler(channelManager.timeout_Elapsed);
                timeout.Enabled = true;
                initialized = true;
            }
        }

        #region IValidationManagerRemoting Members

        /// <summary>
        /// Returns true if the user exists.
        /// </summary>
        /// <param name="Username">The username.</param>
        /// <returns></returns>
        public bool DoesUserExist(string Username)
        {
            // First approach that results in a timeout after 10 calls
            //IValidationManagerRemoting proxy = new ChannelFactory<IValidationManagerRemoting>(endpointName).CreateChannel();
            //return proxy.DoesUserExist(Username);

            // Second approach that is fast, but we do not know what is going on behind the scenes
            //return Channel.DoesUserExist(Username);

            // Third approach that is slow, but we explicitly manage what is going on
            //IValidationManagerRemoting proxy = new ChannelFactory<IValidationManagerRemoting>(endpointName).CreateChannel();
            //bool doesUserExist = proxy.DoesUserExist(Username);
            //((System.ServiceModel.ICommunicationObject)proxy).Close();
            //return doesUserExist;

            // Fourth approach with performance and manual resource handling
            Initialize();
            bool doesUserExist = channelManager.ChannelSetup(ChannelTask.Open).DoesUserExist(Username);
            return doesUserExist;
        }

        public bool DoesUserExistPass(string Username, string Password)
        {
            Initialize();
            bool doesUserExistPass = channelManager.ChannelSetup(ChannelTask.Open).DoesUserExistPass(Username, Password);
            return doesUserExistPass;
        }

        public bool IsUserInRole(string ApplicationName, string RoleName, string UserName)
        {
            Initialize();
            bool isUserInRole = channelManager.ChannelSetup(ChannelTask.Open).IsUserInRole(ApplicationName, RoleName, UserName);
            return isUserInRole;
        }

        public bool IsUserInRolePass(string ApplicationName, string RoleName, string UserName, string Password)
        {
            Initialize();
            bool isUserInRolePass = channelManager.ChannelSetup(ChannelTask.Open).IsUserInRolePass(ApplicationName, RoleName, UserName, Password);
            return isUserInRolePass;
        }

        public List<EnterpriseServices.DalEf.User> GetUsersByApplicationName(string ApplicationName)
        {
            Initialize();
            List<EnterpriseServices.DalEf.User> getUsersByApplicationName = channelManager.ChannelSetup(ChannelTask.Open).GetUsersByApplicationName(ApplicationName);
            return getUsersByApplicationName;
        }

        public bool IsGroupInRole(string ApplicationName, string RoleName, string GroupName)
        {
            Initialize();
            bool isGroupInRole = channelManager.ChannelSetup(ChannelTask.Open).IsGroupInRole(ApplicationName, RoleName, GroupName);
            return isGroupInRole;
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            timeout.Enabled = false;
            channelManager.ChannelSetup(ChannelTask.Close);
        }

        #endregion


        #region Variables declaration

        private static ValidationManagerRemotingProxy SHARED_INSTANCE = new ValidationManagerRemotingProxy();

        bool initialized                    = false;
        const string endpointName           = "IValidationManagerRemoting.Endpoint";
        ChannelManager<IValidationManagerRemoting> channelManager = new ChannelManager<IValidationManagerRemoting>(endpointName);
        System.Timers.Timer timeout         = new System.Timers.Timer(60000); // this should not below 1000, else there is no benefit

        #endregion


    }
}
